package 预科0102;
import java.util.Arrays;
import java.util.Scanner;

/*编程实现控制台版并支持两人对战的五子棋游戏。 
（1）绘制棋盘 - 写一个成员方法实现 
（2）提示黑方和白方分别下棋并重新绘制棋盘 - 写一个成员方法实现。 
（3）每当一方下棋后判断是否获胜 - 写一个成员方法实现。 
 */
import javax.sound.midi.Soundbank;
//类：棋局
public class Chess {
	//横坐标
	private static int x;
	//纵坐标
	private static int y;
	//是否为黑方轮次 是：1 否：-1
	private static int ifBlack=1;
	//成员变量：棋盘
	private static int[][] chessboard=new int[20][20];

	public static void main(String[] args) {
		//创建20*20的二维数组,其中第2行/列作为坐标索引，第1行/列、最后2行/列作为扩展，不能落棋，实际棋盘大小为16x16
		Chess chess=new Chess();
		chess.chessBoardPrint();
		boolean ifDraw;
		do{
			ifDraw=chess.playChessAndPrint();
		}while(chess.ifGameEnd()==false&&ifDraw==false);
		
		
	}
	//成员方法1：绘制棋盘
	public void chessBoardPrint(){
		//第2行/列的第2~17个元素为0-15
		for(int i=2;i<18;i++) {
			chessboard[1][i]=i-2;
			chessboard[i][1]=i-2;
		}
				//双重循环赋值棋盘
		for(int i=2;i<18;i++) {
			for(int j=2;j<18;j++) {
				//判断若数组元素为初始值 空，即打印*
				chessboard[i][j]=-100;
			}
		}
		//双重循环打印棋盘
		for(int i=1;i<18;i++) {
			for(int j=1;j<18;j++) {
				//判断若数组元素为初始值 空，即打印*
				if(chessboard[i][j]==-100) {
					System.out.print("*"+"  ");
				}else if (i==1&&j==1){
					System.out.print("   ");
				}else {
					System.out.printf("%x",chessboard[i][j]);
					System.out.print("  ");
				}
			}
			//换行
			System.out.println();
		}
	}
	
	//成员方法2.1：索引转换为棋盘下标
	public int index(String str) {
		switch(str) {
		case "0": return 2;
		case "1": return 3;
		case "2": return 4;
		case "3": return 5;
		case "4": return 6;
		case "5": return 7;
		case "6": return 8;
		case "7": return 9;
		case "8": return 10;
		case "9": return 11;
		case "a": return 12;
		case "b": return 13;
		case "c": return 14;
		case "d": return 15;
		case "e": return 16;
		case "f": return 17;
		}
		return 0;
	}
	//成员方法2：提示黑方和白方分别下棋并重新绘制棋盘 返回棋盘是否已满。
	public boolean playChessAndPrint(){
		//提示黑方和白方分别下棋
		Scanner scan=new Scanner(System.in);
		//判断棋盘是否已满
		int sumSpace=0;
		for(int i=2;i<18;i++) {
			for(int j=2;j<18;j++) {
				//判断若数组元素为初始值 空，计数
				if(chessboard[i][j]==-100) {
					sumSpace++;
				}
			}
		}
		if(sumSpace==0) {
			System.out.println("棋盘已满，平局");
			//平局时返回true
			return true;
		}
		//黑方轮次
		if(ifBlack==1) {
			do{
				//判断索引是否超出界限
				do {
				System.out.println("请黑方输入棋子横坐标（0-f）：");
				x=index(scan.next());
				}while (x==0); 
				do {
				System.out.println("请黑方输入棋子纵坐标（0-f）：");
				y=index(scan.next());
				}while (y==0); 
				//判断落棋位置是否为空
				if(chessboard[x][y]!=-100) {
					System.out.println("该位置已有棋子");
				}
			}while(chessboard[x][y]!=-100);
			//黑棋落子赋值为1
			chessboard[x][y]=1;
			//转换轮次
			ifBlack=-1;
			
		}else {
			do{
				//判断索引是否超出界限
				do {
				System.out.println("请白方输入棋子横坐标（0-f）：");
				x=index(scan.next());
				}while (x==0); 
				do {
				System.out.println("请白方输入棋子纵坐标（0-f）：");
				y=index(scan.next());
				}while (y==0); 
				//判断落棋位置是否为空
				if(chessboard[x][y]!=-100) {
					System.out.println("该位置已有棋子");
				}
			}while(chessboard[x][y]!=-100);
			//白棋落子赋值为-1
			chessboard[x][y]=-1;
			//转换轮次
			ifBlack=1;
		}
		//双重循环打印棋盘
		for(int i=1;i<18;i++) {
			for(int j=1;j<18;j++) {
				
				if(i==1&&j==1){
					System.out.print("   ");
				}
				//1行/列为索引
				else if (i==1||j==1) {
					System.out.printf("%x",chessboard[i][j]);
					System.out.print("  ");
				}//判断若数组元素为初始值 空，即打印*
				else if(chessboard[i][j]==-100) {
					System.out.print("*"+"  ");
				}//chessboard[1][1]处为空
				else if (i==1&&j==1){
					System.out.print("   ");
				}//chessboard[i][j]==1处为黑棋，显示为b
				else if (chessboard[i][j]==1){
					System.out.print("b"+"  ");
				}//chessboard[i][j]==-1处为白棋，显示为w
				else if (chessboard[i][j]==-1){
					System.out.print("w"+"  ");
				}
			}
			//换行
			System.out.println();
		}
		return false;
	}
	//成员方法3：每当一方下棋后判断是否获胜
	public boolean ifGameEnd(){
		//存放横向5个棋子的和
		int sumTransverse=0;
		//存放纵向5个棋子的和
		int sumVertical=0;
		//存放左上角到右下角5个棋子的和
		int sumLeftToRight=0;
		//存放右上角到左下角5个棋子的和
		int sumRightToLeft=0;
		//双重循环判断胜负
		for(int i=2;i<18;i++) {
			for(int j=2;j<18;j++) {
				sumTransverse=chessboard[i-2][j]+chessboard[i-1][j]+chessboard[i][j]+chessboard[i+1][j]+chessboard[i+2][j];
				sumVertical=chessboard[i][j-2]+chessboard[i][j-1]+chessboard[i][j]+chessboard[i][j+1]+chessboard[i][j+2];
				sumLeftToRight=chessboard[i-2][j+2]+chessboard[i-1][j+1]+chessboard[i][j]+chessboard[i+1][j-1]+chessboard[i+2][j-2];
				sumRightToLeft=chessboard[i-2][j-2]+chessboard[i-1][j-1]+chessboard[i][j]+chessboard[i+1][j+1]+chessboard[i+2][j+2];
				if(ifBlack==-1&&(sumTransverse==5||sumVertical==5||sumLeftToRight==5||sumRightToLeft==5)) {
					System.out.print("黑方获胜！游戏结束");
					return true;
				}else if(ifBlack==1&&(sumTransverse==-5||sumVertical==-5||sumLeftToRight==-5||sumRightToLeft==-5)) {
					System.out.print("白方获胜！游戏结束");
					return true;
				}
			}
		}
		return false;
	}
}

